fix(calibration): light native charts (drop dark server SVGs)#42
Merged
Conversation
…suals The bottom calibration charts were gbrain's dark-themed server-rendered SVGs (#0a0a0f bg) embedded as <img> on Lore's light page — black boxes with dim, hard-to-read text, and the per-domain/abandoned ones were empty anyway. Render them natively from the profile JSON instead, on Lore's light theme: - Brier vs baseline gauge (0–0.5 track, 0.25 baseline marker, green ≤0.25 else amber) - Accuracy gauge (0–100%) - Outcomes split bar (correct/incorrect/partial), reconstructed from the scorecard aggregates via calibrationOutcomes() (pure, unit-tested) Drops the CHARTS <img> fan-out (4 dark SVGs). typecheck + vitest (75) + next build all green; routes stay dynamic. Co-Authored-By: Zypher Agent <zypher@corespeed.io>
spinsirr
added a commit
that referenced
this pull request
Jul 7, 2026
biome check has been failing repo-wide since the calibration/admin PRs landed with unformatted files, so every branch inherits a red CI check. Formatting-only; no behavior change. Co-Authored-By: Zypher Agent <zypher@corespeed.io>
spinsirr
added a commit
that referenced
this pull request
Jul 7, 2026
* fix(graph): traverse from relevant hubs, not the newest pages
The graph rendered as all-isolated dots ("全散了") — every node degree 0,
uniform size, no edges — even though the brain has a dense link graph.
Root cause: #45 picks the deep-traversal roots as
`[...titles.keys()].slice(0, TRAVERSE_ROOTS)`. `titles` is filled
list_pages-first in updated_desc order, so the roots are just the 8
NEWEST pages — which are frequently freshly-created and not yet linked.
A depth-5 traversal from an unlinked page reaches nothing, and the rich
hubs (entities/haas, companies/corespeed) sit at position #9+, excluded
from the roots. Result: 0 edges, deterministically.
- Seed the traversal roots from the seed-query hits (relevance-ranked,
round-robin across queries so each contributes its top hit), which
reliably surface the hubs; fall back to recent pages only to fill
TRAVERSE_ROOTS. On the live brain this restores 0 → 87 edges.
- edgeRows now reports ok/failure instead of collapsing both to []. When
the graph ends up edgeless AND a traversal actually errored, buildGraph
throws so /api/graph returns 502 (uncached) rather than caching a
misleading scattered graph for the full 1h TTL.
- Add a test for the fail-loud path; update AGENTS.md graph bullet (which
still described the pre-#43 get_links implementation).
Co-Authored-By: Zypher Agent <zypher@corespeed.io>
* chore: format admin files left unformatted by #42/#44
biome check has been failing repo-wide since the calibration/admin PRs
landed with unformatted files, so every branch inherits a red CI check.
Formatting-only; no behavior change.
Co-Authored-By: Zypher Agent <zypher@corespeed.io>
* fix(graph): close the fail-loud guard's blind spots + serve stale over 502
Review hardening on top of the hub-roots fix (multi-model review of
this PR):
- Every upstream read feeds ONE failure signal: seed queries and
list_pages now track failures (a total outage used to cache an EMPTY
graph as healthy for the 1h TTL; an all-seed-query failure silently
reverted roots to recency order — the exact regression this PR
fixes). edgeRows treats MCP isError results, non-array payloads, and
edge-row-less arrays (schema drift) as failed reads instead of
"healthy, zero edges".
- The edgeless guard gates on the PRE-filter edge set, so a brain
whose every edge touches a hash-titled page doesn't 502.
- Degraded builds (some reads failed, edges survived) are served but
NOT cached, so a partial graph can't get pinned for the full TTL.
- Rebuilds are single-flighted, and a failed rebuild serves the last
good expired graph stale instead of a 502 — no full-pipeline retry
storm against an already-degraded gbrain.
- The route logs the failure reason before the generic 502.
- Overview renders the link stat as "—" and TopHubs says the data is
unavailable when the graph read failed, instead of a misleading 0.
- Hash-titled mem0 imports no longer consume traversal-root slots.
- Tests: root selection is pinned (reverting to recency-ordered roots
fails the suite — mutation-verified), plus coverage for the
uncached-throw contract, isError, total outage, partial failure,
stale-serve, single-flight, round-robin order, and the route 502.
Co-Authored-By: Zypher Agent <zypher@corespeed.io>
---------
Co-authored-by: Zypher Agent <zypher@corespeed.io>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bottom calibration charts were gbrain's dark server-rendered SVGs embedded as
<img>on Lore's light page → black boxes with dim text (and per-domain/abandoned were empty). Render natively from the profile JSON on Lore's light theme:calibrationOutcomes()— pure, unit-tested (reconstructs counts from the scorecard aggregates)Drops the 4 dark
<img>charts. typecheck + vitest 75 + next build green.